home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Applications / Python 1.3.3 / stdwin / Packs / textedit / editwin.c next >
Text File  |  1995-12-21  |  8KB  |  464 lines

  1. /* Edit Windows */
  2.  
  3. /* The data structure exported by this module is intended to
  4.    be accessible to the caller;
  5.    the routines provided here don't duplicate operations that
  6.    can be done by calling text-edit or window routines directly.
  7.    Exception: ewreplace is like tereplace, but also clears
  8.    the 'saved' flag and sets the document size */
  9.  
  10. #include "stdwin.h"
  11. #include "tools.h"
  12. #include "editwin.h"
  13.  
  14. extern long ftell _ARGS((FILE *));
  15.  
  16. #define MAXFN 256 /* File name length */
  17.  
  18. static int ewnum;
  19. static EDITWIN **ewlist;
  20.  
  21. EDITWIN *
  22. ewfind(win)
  23.     WINDOW *win;
  24. {
  25.     int i;
  26.  
  27.     if (win == NULL)
  28.         return NULL;
  29.  
  30.     i= wgettag(win);
  31.     
  32.     if (i >= 0 && i < ewnum &&
  33.             ewlist[i] != NULL && ewlist[i]->win == win)
  34.         return ewlist[i];
  35.     else
  36.         return NULL;
  37. }
  38.  
  39. int
  40. ewcount()
  41. {
  42.     int count= 0;
  43.     int i;
  44.     for (i= 0; i < ewnum; ++i) {
  45.         if (ewlist[i] != NULL)
  46.             ++count;
  47.     }
  48.     return count;
  49. }
  50.  
  51. static void
  52. ewdrawproc(win, left, top, right, bottom)
  53.     WINDOW *win;
  54. {
  55.     EDITWIN *ew= ewfind(win);
  56.     if (ew != NULL)
  57.         tedrawnew(ew->tp, left, top, right, bottom);
  58. }
  59.  
  60. EDITWIN *
  61. ewcreate(filename)
  62.     char *filename;
  63. {
  64.     EDITWIN *ew= ALLOC(EDITWIN);
  65.     int width, height;
  66.     int hbar, vbar;
  67.     int i;
  68.     
  69.     if (ew == NULL)
  70.         return NULL;
  71.     wgetdefscrollbars(&hbar, &vbar);
  72.     wsetdefscrollbars(0, 1);
  73.     ew->win= wopen(filename==NULL ? "Untitled" : filename, ewdrawproc);
  74.     wsetdefscrollbars(hbar, vbar);
  75.     if (ew->win == NULL) {
  76.         FREE(ew);
  77.         return NULL;
  78.     }
  79.     wsetwincursor(ew->win, wfetchcursor("ibeam"));
  80.     wgetwinsize(ew->win, &width, &height);
  81.     ew->tp= tecreate(ew->win, 0, 0, width, height);
  82.     if (ew->tp == NULL) {
  83.         wclose(ew->win);
  84.         FREE(ew);
  85.         return NULL;
  86.     }
  87.     if (filename != NULL) {
  88.         if (!ewreadfile(ew, filename)) {
  89.             tefree(ew->tp);
  90.             wclose(ew->win);
  91.             FREE(ew);
  92.             return NULL;
  93.         }
  94.     }
  95.     ew->filename= strdup(filename);
  96.     ew->saved= TRUE;
  97.     for (i= 0; i < ewnum; ++i) {
  98.         if (ewlist[i] == NULL)
  99.             break;
  100.     }
  101.     wsettag(ew->win, i);
  102.     if (i >= ewnum) {
  103.         L_APPEND(ewnum, ewlist, EDITWIN*, NULL);
  104.     }
  105.     ewlist[i]= ew;
  106.     return ew;
  107. }
  108.  
  109. EDITWIN *
  110. ewnew()
  111. {
  112.     return ewcreate((char*)NULL);
  113. }
  114.  
  115. EDITWIN *
  116. ewopen()
  117. {
  118.     char filename[MAXFN];
  119.     
  120.     filename[0]= EOS;
  121.     if (waskfile("Open file:", filename, sizeof filename, FALSE))
  122.         return ewcreate(filename);
  123.     else
  124.         return NULL;
  125. }
  126.  
  127. bool
  128. ewclose(ew)
  129.     EDITWIN *ew;
  130. {
  131.     int i;
  132.     
  133.     if (!ew->saved) {
  134.         char buf[MAXFN+25];
  135.         sprintf(buf, "Save changes to \"%s\" before closing?",
  136.             ew->filename==NULL ? "Untitled" : ew->filename);
  137.         switch (waskync(buf, 1)) {
  138.         case -1:
  139.             return FALSE;
  140.         case 0:
  141.             break;
  142.         case 1:
  143.             if (!ewsave(ew))
  144.                 return FALSE;
  145.             break;
  146.         }
  147.     }
  148.     i= wgettag(ew->win);
  149.     if (i >= 0 && i < ewnum && ewlist[i] == ew)
  150.         ewlist[i]= NULL;
  151.     tefree(ew->tp);
  152.     wclose(ew->win);
  153.     FREE(ew->filename);
  154.     FREE(ew);
  155.     return TRUE;
  156. }
  157.  
  158. bool
  159. ewsave(ew)
  160.     EDITWIN *ew;
  161. {
  162.     if (ew->saved)
  163.         return TRUE;
  164.     if (!ew->filename)
  165.         return ewsaveas(ew);
  166.     return ew->saved= ewwritefile(ew, ew->filename);
  167. }
  168.  
  169. bool
  170. ewsaveas(ew)
  171.     EDITWIN *ew;
  172. {
  173.     return ewsaveprompt(ew, "Save as:", TRUE);
  174. }
  175.  
  176. bool
  177. ewsavecopy(ew)
  178.     EDITWIN *ew;
  179. {
  180.     return ewsaveprompt(ew, "Save a copy as:", FALSE);
  181. }
  182.  
  183. bool
  184. ewsaveprompt(ew, prompt, changefile)
  185.     EDITWIN *ew;
  186.     char *prompt;
  187.     bool changefile;
  188. {
  189.     char filename[MAXFN];
  190.     
  191.     filename[0]= EOS;
  192.     if (ew->filename != NULL) {
  193.         strncpy(filename, ew->filename, MAXFN);
  194.         filename[MAXFN-1]= EOS;
  195.     }
  196.     if (!waskfile(prompt, filename, sizeof filename, TRUE))
  197.         return FALSE;
  198.     if (!ewwritefile(ew, filename))
  199.         return FALSE;
  200.     if (changefile) {
  201.         FREE(ew->filename);
  202.         ew->filename= strdup(filename);
  203.         wsettitle(ew->win, filename);
  204.         ew->saved= TRUE;
  205.     }
  206.     return TRUE;
  207. }
  208.  
  209. bool
  210. ewrevert(ew)
  211.     EDITWIN *ew;
  212. {
  213.     char buf[MAXFN+50];
  214.     
  215.     if (ew->saved)
  216.         return TRUE;
  217.     if (ew->filename == NULL) {
  218.         wmessage("Not saved yet");
  219.         return FALSE;
  220.     }
  221.     sprintf(buf, "Discard changes since last save to \"%s\" ?",
  222.         ew->filename);
  223.     if (waskync(buf, 1) < 1)
  224.         return FALSE;
  225.     return ewreadfile(ew, ew->filename);
  226. }
  227.  
  228. bool
  229. ewreadfile(ew, filename)
  230.     EDITWIN *ew;
  231.     char *filename;
  232. {
  233.     FILE *fp= fopen(filename, "r");
  234.     long size;
  235.     char *buf;
  236.     
  237.     if (fp == NULL) {
  238.         wperror(filename);
  239.         return FALSE;
  240.     }
  241.     if (fseek(fp, 0L, 2) == -1) {
  242.         wperror (filename);
  243.         fclose (fp);
  244.         return FALSE;
  245.     }
  246.     size= ftell(fp);
  247.     if (size >= 1L<<15) {
  248.         char mbuf[MAXFN + 50];
  249.         sprintf(mbuf, "File \"%s\" is big (%d K).  Still edit?",
  250.             filename, (int) ((size+1023)/1024));
  251.         if (waskync(mbuf, 1) < 1) {
  252.             fclose(fp);
  253.             return FALSE;
  254.         }
  255.     }
  256.     buf= malloc((unsigned)size);
  257.     if (buf == NULL) {
  258.         wmessage("Can't get memory for buffer");
  259.         fclose(fp);
  260.         return FALSE;
  261.     }
  262.     if (fseek(fp, 0L, 0) == -1) {
  263.         wperror (filename);
  264.         fclose (fp);
  265.         return FALSE;
  266.     }
  267.     if ((size = fread(buf, 1, (int) size, fp)) == -1) {
  268.         wmessage("Read error");
  269.         fclose(fp);
  270.         return FALSE;
  271.     }
  272.     fclose(fp);
  273.     tesetbuf(ew->tp, buf, (int) size); /* Gives the buffer away! */
  274.     ew->saved= TRUE;
  275.     ewsetdimensions(ew);
  276.     return TRUE;
  277. }
  278.  
  279. void
  280. ewsetdimensions(ew)
  281.     EDITWIN *ew;
  282. {
  283.     wsetdocsize(ew->win, 0, tegetbottom(ew->tp));
  284. }
  285.  
  286. bool
  287. ewwritefile(ew, filename)
  288.     EDITWIN *ew;
  289.     char *filename;
  290. {
  291.     FILE *fp= fopen(filename, "w");
  292.     char *buf;
  293.     int len, nwritten;
  294.     
  295.     if (fp == NULL) {
  296.         wperror(filename);
  297.         return FALSE;
  298.     }
  299.     buf= tegettext(ew->tp);
  300.     len= strlen(buf);
  301.     nwritten= fwrite(buf, 1, len, fp);
  302.     fclose(fp);
  303.     if (nwritten != len) {
  304.         wmessage("Write error");
  305.         return FALSE;
  306.     }
  307.     /* Can't set saved to TRUE, because of 'save a copy' */
  308.     return TRUE;
  309. }
  310.  
  311. bool
  312. ewevent(ew, e, closed_return)
  313.     EDITWIN *ew;
  314.     EVENT *e;
  315.     bool *closed_return;
  316. {
  317.     bool closed= FALSE;
  318.     bool change= FALSE;
  319.     
  320.     if (ew == NULL) {
  321.         ew= ewfind(e->window);
  322.         if (ew == NULL)
  323.             return FALSE;
  324.     }
  325.     else if (e->window != ew->win)
  326.         return FALSE;
  327.     
  328.     switch (e->type) {
  329.     
  330.     case WE_ACTIVATE:
  331.         break;
  332.         
  333.     case WE_SIZE:
  334.         {
  335.             int width, height;
  336.             wgetwinsize(ew->win, &width, &height);
  337.             temovenew(ew->tp, 0, 0, width, height);
  338.             ewsetdimensions(ew);
  339.         }
  340.         break;
  341.         
  342.     case WE_CLOSE:
  343.         closed= ewclose(ew);
  344.         break;
  345.  
  346.     case WE_COMMAND:
  347.         if (e->u.command == WC_CLOSE) {
  348.             closed= ewclose(ew);
  349.             break;
  350.         }
  351.         /* Else, fall through */
  352.         if (e->u.command == WC_RETURN ||
  353.             e->u.command == WC_TAB ||
  354.             e->u.command == WC_BACKSPACE)
  355.             change= TRUE;
  356.         goto def; /* Go pass it on to teevent */
  357.     
  358.     case WE_MOUSE_DOWN:
  359.         /* Edit the coordinates slightly so teevent always
  360.            believes it is in the rect */
  361.         {
  362.             int left= tegetleft(ew->tp);
  363.             int right= tegetright(ew->tp);
  364.             int top= tegettop(ew->tp);
  365.             int bottom= tegetbottom(ew->tp);
  366.             CLIPMIN(e->u.where.h, left);
  367.             CLIPMAX(e->u.where.h, right);
  368.             CLIPMIN(e->u.where.v, top);
  369.             if (e->u.where.v >= bottom) {
  370.                 e->u.where.v= bottom;
  371.                 e->u.where.h= right;
  372.             }
  373.         }
  374.         /* Fall through */
  375.     default:
  376.     def:
  377.         if (!teevent(ew->tp, e))
  378.             return FALSE;
  379.         if (e->type == WE_CHAR)
  380.             change= TRUE;
  381.         if (change) {
  382.             ew->saved= FALSE;
  383.             ewsetdimensions(ew);
  384.         }
  385.         break;
  386.         
  387.     }
  388.     
  389.     if (closed_return != NULL)
  390.         *closed_return= closed;
  391.     return TRUE;
  392. }
  393.  
  394. bool
  395. ewsaveall()
  396. {
  397.     int i;
  398.     
  399.     for (i= 0; i < ewnum; ++i) {
  400.         if (ewlist[i] != NULL && !ewsave(ewlist[i]))
  401.             return FALSE;
  402.     }
  403.     return TRUE;
  404. }
  405.  
  406. bool
  407. ewcloseall()
  408. {
  409.     int i;
  410.     
  411.     for (i= 0; i < ewnum; ++i) {
  412.         if (ewlist[i] != NULL && !ewclose(ewlist[i]))
  413.             return FALSE;
  414.     }
  415.     return TRUE;
  416. }
  417.  
  418. void
  419. ewreplace(ew, str)
  420.     EDITWIN *ew;
  421.     char *str;
  422. {
  423.     if (*str == EOS && tegetfoc1(ew->tp) == tegetfoc2(ew->tp))
  424.         return;
  425.     tereplace(ew->tp, str);
  426.     ew->saved= FALSE;
  427.     ewsetdimensions(ew);
  428. }
  429.  
  430. /*ARGSUSED*/
  431. void
  432. ewundo(ew)
  433.     EDITWIN *ew;
  434. {
  435.     wfleep();
  436. }
  437.  
  438. void
  439. ewcopy(ew)
  440.     EDITWIN *ew;
  441. {
  442.     int f1= tegetfoc1(ew->tp);
  443.     int f2= tegetfoc2(ew->tp);
  444.     char *text;
  445.     if (f1 == f2)
  446.         wfleep();
  447.     else {
  448.         text= tegettext(ew->tp);
  449.         wsetclip(text+f1, f2-f1);
  450.     }
  451.         
  452. }
  453.  
  454. void
  455. ewpaste(ew)
  456.     EDITWIN *ew;
  457. {
  458.     char *text= wgetclip();
  459.     if (text == NULL)
  460.         wfleep();
  461.     else
  462.         ewreplace(ew, text);
  463. }
  464.